package com.halfsword.creativecraft.block.custom.machine.blockentity.modules;

import com.halfsword.creativecraft.modules.interfaces.IRecipeHandlerFacet;
import net.minecraft.core.BlockPos;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;

/**
 * 基础配方处理模块实现
 * 提供配方处理的基本功能
 */
public abstract class RecipeHandlerModule implements IRecipeHandlerFacet {

    protected final String moduleId;
    protected final ItemHandlerModule itemHandler;
    protected int progress = 0;
    protected int maxProgress = 200;
    protected Level level;
    protected BlockPos pos;
    protected BlockState state;

    public RecipeHandlerModule(String moduleId, ItemHandlerModule itemHandler) {
        this.moduleId = moduleId;
        this.itemHandler = itemHandler;
    }

    @Override
    public String getModuleId() {
        return moduleId;
    }

    @Override
    public void tick(Level level, BlockPos pos, BlockState state) {
        this.level = level;
        this.pos = pos;
        this.state = state;

        if (level.isClientSide()) {
            return; // 客户端不处理配方逻辑
        }

        // 定期检查配方
        updateCurrentRecipe();

        // 处理当前配方
        if (hasActiveRecipe()) {
            progress++;

            if (progress >= maxProgress) {
                craftItem();
                progress = 0;
            }
        } else {
            // 没有有效配方时重置状态
            resetProgress();
        }
    }

    @Override
    public int getProgress() {
        return progress;
    }

    @Override
    public void setProgress(int progress) {
        this.progress = progress;
    }

    @Override
    public int getMaxProgress() {
        return maxProgress;
    }

    @Override
    public void setMaxProgress(int maxProgress) {
        this.maxProgress = maxProgress;
    }

    /**
     * 制作物品
     */
    protected void craftItem() {
        consumeInputs(1);

        // 生成主产品
        ItemStack mainOutput = getMainOutputProduct().copy();
        distributeOutput(mainOutput);

        // 生成副产品（如果有）
        ItemStack byproduct = getByproductOutput().copy();
        if (!byproduct.isEmpty()) {
            distributeOutput(byproduct);
        }
    }

    /**
     * 分发输出物品
     * @param stack 要分发的物品堆栈
     */
    protected void distributeOutput(ItemStack stack) {
        if (stack.isEmpty()) return;

        // 尝试输出槽位
        for (int slot : itemHandler.getOutputSlots()) {
            if (itemHandler.tryInsertItem(stack, slot)) {
                return;
            }
        }

        // 如果所有输出槽位都满了，处理溢出
        handleOutputOverflow(stack);
    }

    /**
     * 处理输出溢出
     * @param stack 溢出的物品堆栈
     */
    protected void handleOutputOverflow(ItemStack stack) {
        // 默认情况下，物品会丢失
        // 子类可以重写此方法以添加自定义溢出处理逻辑
    }

    /**
     * 重置进度
     */
    protected void resetProgress() {
        if (progress > 0) {
            progress = 0;
        }
    }

    /**
     * 获取当前世界
     * @return 当前世界
     */
    protected Level getLevel() {
        return level;
    }

    /**
     * 获取当前位置
     * @return 当前位置
     */
    protected BlockPos getPos() {
        return pos;
    }

    /**
     * 获取当前方块状态
     * @return 当前方块状态
     */
    protected BlockState getBlockState() {
        return state;
    }

    /**
     * 获取物品处理模块
     * @return 物品处理模块
     */
    protected ItemHandlerModule getItemHandler() {
        return itemHandler;
    }

    // ================= 抽象方法 =================
    @Override
    public abstract void updateCurrentRecipe();

    @Override
    public abstract boolean hasActiveRecipe();

    @Override
    public abstract void consumeInputs(int units);

    @Override
    public abstract ItemStack getMainOutputProduct();

    @Override
    public abstract ItemStack getByproductOutput();

    @Override
    public abstract void onRecipeChanged();

    @Override
    public abstract Recipe<?> getCurrentRecipe();

    @Override
    public abstract boolean hasInput();

    @Override
    public abstract boolean hasOutputSpace();

    @Override
    public abstract int calculateBatchSize();
}